"""
@author: xxw
@file: 07.进程池.py
@time: 2023/7/3 11:12
"""
# 进程池的子进程的个数一般得和cpu的核数一致
# 进程池的作用：有效的降低频繁创建销毁线程所带来的额外开销

'''
# 进程池的原理：
• 进程池都是采用预创建的技术，在应用启动之初便预先创建一定数目的进程。
• 应用在运行的过程中，需要时可以从这些进程所组成的进程池里申请分配一个空闲的进程，来执
行一定的任务，任务完成后，并不是将进程销毁，而是将它返还给进程池，由线程池自行管理。
• 如果进程池中预先分配的线程已经全部分配完毕，但此时又有新的任务请求，则进程池会动态的
创建新的进程去适应这个请求。
• 某些时段应用并不需要执行很多的任务，导致了进程池中的线程大多处于空闲的状态，为了节省
系统资源，进程池就需要动态的销毁其中的一部分空闲进程。
• 进程需要一个管理者，按照一定的要求去动态的维护其中进程的数目。
'''

# from multiprocessing import current_process, Pool
#
# import time
#
# def task(i):
#     print(current_process().name, f"start.......{i}")
#     time.sleep(2)
#     print(current_process().name, f"end.....{i}")
#
# if __name__ == "__main__":
#     # 创建一个进程池，建议进程数与cpu的核数一致
#     # maxtasksperchild 指定每个子进程最多处理多少个任务
#     # 达到响应的任务数后，当前进程就会退出，开启新的任务（可以达到定期释放资源的效果）
#     p = Pool(processes=4, maxtasksperchild=2)
#     for i in range(20):
#         # 进程池接收任务
#         p.apply_async(func=task, args=(i,))
#     # 关闭进程池，不接受任务
#     p.close()
#     # 阻塞当前环境
#     p.join()
#     print("end........process")

################################################
# 多进程vs进程池
from multiprocessing import Process

def task():
    a = 0
    a += 1

if __name__ == "__main__":
    p_list = []
    for i in range(20000):
        p = Process(target=task)
        p.start()
        p_list.append(p)
    [p.join() for p in p_list]
    print("end.......")

# 进程池
from multiprocessing import Pool

def task():
    a = 0
    a += 1

if __name__ == "__main__":
    p = Pool(processes=4)
    for i in range(20000):
        p.apply_async(func=task)
    p.close()
    p.join()
    print("end...........")